package meter

import (
	"context"
	"fmt"
	"regexp"

	"github.com/gogf/gf/v2/frame/g"
)

// TimeType represents the time type for statistical requests
// TimeType 表示统计请求的时间类型
type TimeType string

// TimeType constants for StatisticEleRequest
// StatisticEleRequest 的时间类型常量
const (
	TimeTypeHour  TimeType = "hour"  // 小时
	TimeTypeDay   TimeType = "day"   // 日
	TimeTypeMonth TimeType = "month" // 月
	TimeTypeYear  TimeType = "year"  // 年
)

// String returns the string representation of TimeType
// String 返回 TimeType 的字符串表示
func (t TimeType) String() string {
	return string(t)
}

// IsValid checks if the TimeType is one of the valid values
// IsValid 检查 TimeType 是否为有效值
func (t TimeType) IsValid() bool {
	switch t {
	case TimeTypeHour, TimeTypeDay, TimeTypeMonth, TimeTypeYear:
		return true
	default:
		return false
	}
}

// GetTimeFormats returns all valid TimeType values
// GetTimeFormats 返回所有有效的 TimeType 值
func GetTimeFormats() []TimeType {
	return []TimeType{TimeTypeHour, TimeTypeDay, TimeTypeMonth, TimeTypeYear}
}

// StatisticEleRequest represents the request parameters for electrical statistics API
// StatisticEleRequest 表示电表统计API的请求参数
type StatisticEleRequest struct {
	TimeType  TimeType `json:"timeType" v:"required|in:hour,day,month,year"` // 时间类型: hour/day/month/year (使用 TimeType 类型)
	StartTime string   `json:"startTime" v:"required"`                       // 开始时间
	EndTime   string   `json:"endTime" v:"required"`                         // 结束时间
}

// MeterStatistic represents statistical data for a single meter
// MeterStatistic 表示单个电表的统计数据
type MeterStatistic struct {
	D   []float64 `json:"d"`   // 差值数组
	E   []float64 `json:"e"`   // 结束值数组
	ET  string    `json:"et"`  // 结束时间
	MID int       `json:"mid"` // 电表ID
	R   int       `json:"r"`   // 费率
	S   []float64 `json:"s"`   // 开始值数组
	ST  string    `json:"st"`  // 开始时间
}

// StatisticEleData represents the data section of statistics response
// StatisticEleData 表示统计响应的数据部分
type StatisticEleData struct {
	Data   map[string][]MeterStatistic `json:"data"`   // 按日期分组的电表统计数据
	Status int                         `json:"status"` // 状态
}

// StatisticEleResponse represents the complete response from electrical statistics API
// StatisticEleResponse 表示电表统计API的完整响应
type StatisticEleResponse struct {
	Code    int               `json:"code"`    // 响应状态码
	Message string            `json:"message"` // 响应消息
	Data    *StatisticEleData `json:"data"`    // 响应数据
}

// Validate validates the StatisticEleRequest parameters using GoFrame validation
// Validate 使用GoFrame验证StatisticEleRequest参数
func (r *StatisticEleRequest) Validate() error {
	// First validate the struct fields using GoFrame
	if err := g.Validator().Data(r).Run(context.Background()); err != nil {
		return err
	}

	// Validate time format based on timeType
	if err := r.validateTimeFormat(); err != nil {
		return err
	}

	return nil
}

// validateTimeFormat validates the time format based on timeType using regex
// validateTimeFormat 使用正则表达式根据timeType验证时间格式
func (r *StatisticEleRequest) validateTimeFormat() error {
	// 定义时间格式规则映射，使用 TimeType 类型作为 key
	timeFormats := map[TimeType]struct {
		pattern string
		example string
	}{
		TimeTypeHour:  {`^\d{10}$`, "2024081600"}, // YYYYMMDDHH
		TimeTypeDay:   {`^\d{8}$`, "20240816"},    // YYYYMMDD
		TimeTypeMonth: {`^\d{6}$`, "202408"},      // YYYYMM
		TimeTypeYear:  {`^\d{4}$`, "2024"},        // YYYY
	}

	format, exists := timeFormats[r.TimeType]
	if !exists {
		return fmt.Errorf("unsupported timeType: %s", r.TimeType)
	}

	// 使用正则表达式验证时间格式
	matched, _ := regexp.MatchString(format.pattern, r.StartTime)
	if !matched {
		return fmt.Errorf("%s format should be %s (e.g., %s)", r.TimeType, format.pattern[1:len(format.pattern)-1], format.example)
	}

	matched, _ = regexp.MatchString(format.pattern, r.EndTime)
	if !matched {
		return fmt.Errorf("%s format should be %s (e.g., %s)", r.TimeType, format.pattern[1:len(format.pattern)-1], format.example)
	}

	return nil
}
